﻿namespace ReplaceBinary
{
    using System;
    using System.Collections.Generic;
    using System.IO;

    public static class PatchPro
    {
        public static byte[] OpenFile(string filePath)
        {
            byte[] read = { };
            if (File.Exists(filePath))
            {
                FileStream file = File.Open(filePath, FileMode.Open);
                using (var reader = new BinaryReader(file))
                {
                    read = reader.ReadBytes(Convert.ToInt32(file.Length));
                    reader.Close();
                }
            }

            return read;
        }

        public static List<int> FindBytesInBytes(byte[] source, byte[] target)
        {
            var result = new List<int>();
            int point;
            int targetPoint = 0;
            int found = 0;
            for (point = 0; point < source.Length; point++)
            {
                if (source[point] == target[targetPoint])
                {
                    targetPoint++;
                    if (targetPoint == target.Length)
                    {
                        result.Add(found);
                        targetPoint = 0;
                        found = point + 1;
                    }
                }
                else
                {
                    targetPoint = 0;
                    found = point + 1;
                }
            }

            return result;
        }

        public static byte[] ReplaceBytesInBytes(byte[] source, byte[] from, byte[] to)
        {
            List<int> position = FindBytesInBytes(source, from);
            var result = new byte[(position.Count * (to.Length - from.Length)) + source.Length];
            int resultPoint = 0;
            int point = 0;
            for (; point < source.Length;)
            {
                if (position.Contains(point))
                {
                    foreach (byte b in to)
                    {
                        result[resultPoint] = b;
                        resultPoint++;
                    }

                    Console.WriteLine("Replace at Index " + point);
                    point += from.Length;
                }
                else
                {
                    result[resultPoint] = source[point];
                    resultPoint++;
                    point++;
                }
            }

            return result;
        }

        public static void SaveFile(string filePath, byte[] file)
        {
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            using (var writer = new BinaryWriter(new FileStream(filePath, FileMode.OpenOrCreate)))
            {
                writer.Write(file);
                writer.Close();
            }
        }
    }
}